const logger = require('../utils/logger');

/**
 * 安全头部中间件
 */
const securityHeaders = (req, res, next) => {
  // 防止点击劫持
  res.setHeader('X-Frame-Options', 'SAMEORIGIN');
  
  // 防止MIME类型嗅探
  res.setHeader('X-Content-Type-Options', 'nosniff');
  
  // XSS 保护
  res.setHeader('X-XSS-Protection', '1; mode=block');
  
  // 内容安全策略（根据需要调整）
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  
  // 引荐来源策略
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
  
  next();
};

/**
 * SQL 注入防护（基础检测）
 */
const sqlInjectionProtection = (req, res, next) => {
  const dangerousPatterns = [
    /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC|EXECUTE)\b)/gi,
    /(UNION.*SELECT)/gi,
    /(OR\s+\d+\s*=\s*\d+)/gi,
    /(--|\#|\/\*|\*\/)/g
  ];

  const checkValue = (value) => {
    if (typeof value === 'string') {
      for (const pattern of dangerousPatterns) {
        if (pattern.test(value)) {
          return true;
        }
      }
    }
    return false;
  };

  const checkObject = (obj) => {
    for (const key in obj) {
      const value = obj[key];
      if (typeof value === 'object' && value !== null) {
        if (checkObject(value)) return true;
      } else if (checkValue(value)) {
        return true;
      }
    }
    return false;
  };

  // 检查 query、body、params
  if (checkObject(req.query) || checkObject(req.body) || checkObject(req.params)) {
    logger.warn('检测到潜在的 SQL 注入攻击', {
      ip: req.ip,
      url: req.originalUrl,
      method: req.method
    });
    
    return res.status(403).json({
      code: 403,
      msg: '请求包含非法字符'
    });
  }

  next();
};

/**
 * XSS 防护（基础过滤）
 */
const xssProtection = (req, res, next) => {
  const xssPatterns = [
    /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
    /javascript:/gi,
    /on\w+\s*=/gi
  ];

  const sanitizeValue = (value) => {
    if (typeof value === 'string') {
      for (const pattern of xssPatterns) {
        if (pattern.test(value)) {
          logger.warn('检测到潜在的 XSS 攻击', {
            ip: req.ip,
            url: req.originalUrl,
            value: value.substring(0, 100)
          });
          return value.replace(pattern, '');
        }
      }
    }
    return value;
  };

  const sanitizeObject = (obj) => {
    for (const key in obj) {
      if (typeof obj[key] === 'object' && obj[key] !== null) {
        sanitizeObject(obj[key]);
      } else {
        obj[key] = sanitizeValue(obj[key]);
      }
    }
  };

  // 清理 body 和 query
  if (req.body) sanitizeObject(req.body);
  if (req.query) sanitizeObject(req.query);

  next();
};

/**
 * 请求体大小限制检查
 */
const requestSizeLimit = (maxSize = '10mb') => {
  const parseSize = (size) => {
    if (typeof size === 'number') return size;
    const units = { b: 1, kb: 1024, mb: 1024 * 1024, gb: 1024 * 1024 * 1024 };
    const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*([kmg]?b)$/);
    if (!match) return 10 * 1024 * 1024; // 默认 10MB
    return parseFloat(match[1]) * units[match[2]];
  };

  const limit = parseSize(maxSize);

  return (req, res, next) => {
    const contentLength = parseInt(req.get('content-length') || 0);
    
    if (contentLength > limit) {
      logger.warn('请求体大小超过限制', {
        ip: req.ip,
        contentLength,
        limit
      });
      
      return res.status(413).json({
        code: 413,
        msg: '请求体过大'
      });
    }
    
    next();
  };
};

module.exports = {
  securityHeaders,
  sqlInjectionProtection,
  xssProtection,
  requestSizeLimit
};

